package com.zxt.lock.aspect;

import com.zxt.bean.ResultCode;
import com.zxt.bean.ServiceException;
import com.zxt.lock.RedissonLock;
import com.zxt.lock.annotation.DistributedLock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * aop实现:为添加了@DistributedLock注解的类、方法加入分布式锁
 *
 * @author zxt
 */
@Aspect
@Component
public class DistributedLockHandler {
    private static final Logger log = LoggerFactory.getLogger(DistributedLockHandler.class);
    private final RedissonLock redissonLock;

    /**
     * aop环绕通知
     *
     * @param joinPoint
     * @param distributedLock
     * @return
     * @throws Throwable
     */
    @Around("@annotation(distributedLock)")
    public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
        log.info("[开始]执行RedisLock环绕通知,获取Redis分布式锁开始");
        String lockName = distributedLock.value();
        int waitTime = distributedLock.waitTime();
        int leaseTime = distributedLock.leaseTime();
        boolean isLock = this.redissonLock.lock(lockName, (long) waitTime, (long) leaseTime);
        if (isLock) {
            label39:
            {
                Object var6;
                try {
                    log.info("获取Redis分布式锁[成功]，加锁完成，开始执行业务逻辑...");
                    var6 = joinPoint.proceed();
                } catch (Throwable e) {
                    log.error("获取Redis分布式锁[异常]，加锁失败", e);
                    e.printStackTrace();
                    throw new ServiceException(ResultCode.COMMON_MESSAGE, e.getMessage());
                    /*break label39;*/
                } finally {
                    this.redissonLock.release(lockName);
                    log.info("释放Redis分布式锁[成功]，解锁完成，结束业务逻辑...");
                }
                log.info("[结束]执行RedisLock环绕通知");
                return var6;
            }
        } else {
            log.error("获取Redis分布式锁[失败]");
        }

        log.info("[结束]执行RedisLock环绕通知");
        return null;
    }

    public DistributedLockHandler(final RedissonLock redissonLock) {
        this.redissonLock = redissonLock;
    }
}
